using Nekonya.Components.Interactive;
using Nekonya.Const;
using TinaX;
using UnityEngine;
using UnityEngine.Events;

namespace Nekonya.Components
{
    public class PlayerRay : MonoBehaviour
    {
        [Header("玩家视角相机")]
        public Camera PlayerCamera;

        [Header("观察交互 范围（米）")]
        public float WatchableRange = 4f;

        [Header("调试射线")]
        public bool DebugRay = false;

        [Space]
        public UnityEvent<Watchable> _OnWatch = new UnityEvent<Watchable>();
        public UnityEvent<Watchable> _LostWatch = new UnityEvent<Watchable>();


        /// <summary>
        /// 屏幕中心点坐标
        /// </summary>
        private Vector3 m_ScreenCenterV3;

        private RaycastHit m_Hit;

        private Collider m_LastHit;
        private bool m_LastHitFlag = false;

        /// <summary>
        /// 开火状态
        /// </summary>
        private bool m_OnFire = false;


        private void Awake()
        {
            m_ScreenCenterV3 = new Vector3(Screen.width / 2, Screen.height / 2, 0);
        }


        private void Update()
        {
            #region 射线处理

            if (Input.GetButtonDown("Fire1"))
                m_OnFire = true;
            else
                m_OnFire = false;

            Ray ray = PlayerCamera.ScreenPointToRay(m_ScreenCenterV3);
#if UNITY_EDITOR
            if (DebugRay)
            {
                Vector3 forword = ray.direction * (m_OnFire ? 1000 : WatchableRange);
                //调试射线
                Debug.DrawRay(ray.origin, forword, Color.red, 0);
            }
#endif
            

            if (Physics.Raycast(ray, out m_Hit, m_OnFire? Mathf.Infinity : WatchableRange))
            {
                
                if(!m_OnFire && m_Hit.collider.CompareTag("Watchable"))
                {
                    if (!m_LastHitFlag || m_LastHit != m_Hit.collider)
                    {
                        m_LastHit = m_Hit.collider;
                        m_LastHitFlag = true;
                        var watchable = m_Hit.collider.GetComponent<Watchable>();
                        if (watchable != null)
                        {
                            _OnWatch?.Invoke(watchable);
                            XEvent.Call(EventConst.OnPlayerWatch, watchable);
                            Debug.Log("正在注视着可观察物：" + m_Hit.collider.transform.name);
                        }
                    }
                }
            }
            else
            {
                if(m_LastHit != null)
                {
                    Debug.Log("不再注视可观察物：" + m_LastHit.name);
                    XEvent.Call(EventConst.PlayerLostWatch);
                    m_LastHit = null;
                    m_LastHitFlag = false;
                }

                if (m_LastHitFlag && m_LastHit == null)
                {
                    //当前明明应该是“OnWatch”的状态，但是Watch的对象仿佛丢失了
                    m_LastHitFlag = false;
                    m_LastHit = null;
                    Debug.Log("可观察物丢失");
                    _LostWatch.Invoke(null);
                    XEvent.Call(EventConst.PlayerLostWatch);
                }
            }

            #endregion

            if (Input.GetKeyDown(KeyCode.F))
            {
                if(m_LastHitFlag && m_LastHit != null)
                {
                    var watchable = m_LastHit.GetComponent<Watchable>();
                    if (watchable)
                    {
                        if(watchable is InteractiveObservationComponent)
                        {
                            var _io = (InteractiveObservationComponent)watchable;
                            _io.Do();
                        }
                    }
                }
            }
        }
    }
}
